using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.IO;


namespace EEst.Tools.VsPackageNMakeAdapter
{

    class XCMakefileGenerator
    {
        private string cygwinHomeDir = "";
        public string CygwinHomeDir
        {
            get { return cygwinHomeDir; }
            set { cygwinHomeDir = value; }
        }

        private string brickOSDir = "";
        public string BrickOSDir
        {
            get { return brickOSDir; }
            set { brickOSDir = value; }
        }

        private string xcHomeDir = "";
        public string XCHomeDir
        {
            get { return xcHomeDir; }
            set { xcHomeDir = value; }
        }

        private List<string> incDirs = new List<string>();
        public string IncDirs
        {
            get
            {
                StringBuilder buf = new StringBuilder();
                foreach (string incDir in incDirs)
                {
                    buf.Append(" -I");
                    //buf.Append(incDir.Replace('\\', '/'));
                    buf.Append(incDir);
                }
                return buf.ToString();
            }
        }

        public string[] GetIncDirs()
        {
            return incDirs.ToArray();
        }

        private List<string> srcFiles = new List<string>();


        private string templateFile;
        public string TemplateFile
        {
            get
            {
                return templateFile;
            }
            set { templateFile = value; }
        }

        private string outputFile;
        public string OutputFile
        {
            get { return outputFile; }
            set { outputFile = value; }
        }

        private string target;
        public string Target
        {
            get { return target; }
            set { target = value; }
        }

        public void AddIncDir(string incDir)
        {
            if (incDir.Length == 0) return;
            incDirs.Add(incDir);
        }

        public void ClearIncDirs()
        {
            incDirs.Clear();
        }

        public void AddSrcFile(string srcFile)
        {
            if (!srcFiles.Contains(srcFile)) srcFiles.Add(srcFile);
        }

        public void RemoveSrcFile(string srcFile)
        {
            if (srcFiles.Contains(srcFile)) srcFiles.Remove(srcFile);
        }

        public void ClearSrcFiles()
        {
            srcFiles.Clear();
        }

        public string[] GetSrcFiles()
        {
            return srcFiles.ToArray();
        }

        private List<string> ccFlags = new List<string>();
        public void AddCCFlag(string flag)
        {
            ccFlags.Add(flag);
        }

        public void ClearCCFlags()
        {
            ccFlags.Clear();
        }

        public string[] GetCCFlags()
        {
            return ccFlags.ToArray();
        }

        private string mkTargetPath;

        public XCMakefileGenerator(string targetPath,string makefile, string configFileName)
        {
            mkTargetPath = targetPath;
            _configFileName = configFileName;
            configFile = mkTargetPath + "\\" + _configFileName;
            outputFile = mkTargetPath + "\\" + makefile;

            if (File.Exists(configFile))
            {
                XmlDocument doc = new XmlDocument();
                using (FileStream stream = new FileStream(configFile, FileMode.Open, FileAccess.Read))
                {
                    doc.Load(stream);
                    XPathNavigator navi = doc.CreateNavigator();
                    XPathNodeIterator itr = navi.Select("XCConfig/Variables/Variable");
                    while (itr.MoveNext())
                    {
                        string varName = itr.Current.GetAttribute("name", String.Empty);
                        string varValue = itr.Current.GetAttribute("value", String.Empty);
                        if (varName.CompareTo(VARIABLE_KEY.BRICKOS_HOME.ToString()) == 0)
                        {
                            brickOSDir = varValue;
                        }
                        else if (varName.CompareTo(VARIABLE_KEY.CYGWIN_HOME.ToString()) == 0)
                        {
                            cygwinHomeDir = varValue;
                        }
                        else if (varName.CompareTo(VARIABLE_KEY.XC_TOOLS_HOME.ToString()) == 0)
                        {
                            xcHomeDir = varValue;
                        }
                        else if (varName.CompareTo(VARIABLE_KEY.TARGET.ToString()) == 0)
                        {
                            target = varValue;
                        }
                    }
                    itr = navi.Select("XCConfig/CCFlags/CCFlag");
                    while (itr.MoveNext())
                    {
                        string content = itr.Current.Value;
                        ccFlags.Add(content);
                    }
                    itr = navi.Select("XCConfig/IncDirs/IncDir");
                    while (itr.MoveNext())
                    {
                        string content = itr.Current.Value;
                        AddIncDir(content);
                    }
                    itr = navi.Select("XCConfig/SrcFiles/SrcFile");
                    while (itr.MoveNext())
                    {
                        string content = itr.Current.Value;
                        srcFiles.Add(content);
                    }
                    stream.Close();
                }
            }

        }
        public void Reset()
        {
            incDirs.Clear();
            srcFiles.Clear();
            ccFlags.Clear();
        }

        public void Generate()
        {
            XCMakefileTemplate template = new XCMakefileTemplate();
            template.CYGWIN_HOME = cygwinHomeDir;
            template.BRICKOS_HOME = brickOSDir;
            template.XC_TOOLS_HOME = xcHomeDir;
            template.INC_DIRS = IncDirs;
            template.SRC_FILES = srcFiles.ToArray();
            template.TARGET = target;

            string content = template.Generate();
            File.WriteAllText(OutputFile, content);

            using (FileStream stream = new FileStream(configFile, FileMode.Create, FileAccess.Write))
            {
                XmlDocument doc = new XmlDocument();
                XmlElement docElem = doc.CreateElement("XCConfig");
                doc.AppendChild(docElem);
                XmlElement varsElem = doc.CreateElement("Variables");
                docElem.AppendChild(varsElem);

                XmlElement elem = doc.CreateElement("Variable");
                elem.SetAttribute("name", VARIABLE_KEY.CYGWIN_HOME.ToString());
                elem.SetAttribute("value", CygwinHomeDir);
                varsElem.AppendChild(elem);
                elem = doc.CreateElement("Variable");
                elem.SetAttribute("name", VARIABLE_KEY.BRICKOS_HOME.ToString());
                elem.SetAttribute("value", BrickOSDir);
                varsElem.AppendChild(elem);
                elem = doc.CreateElement("Variable");
                elem.SetAttribute("name", VARIABLE_KEY.XC_TOOLS_HOME.ToString());
                elem.SetAttribute("value", XCHomeDir);
                varsElem.AppendChild(elem);
                elem = doc.CreateElement("Variable");
                elem.SetAttribute("name", VARIABLE_KEY.TARGET.ToString());
                elem.SetAttribute("value", Target);
                varsElem.AppendChild(elem);

                XmlElement ccFlagsElem = doc.CreateElement("CCFlags");
                docElem.AppendChild(ccFlagsElem);
                foreach (string flag in ccFlags)
                {
                    elem = doc.CreateElement("CCFlag");
                    XmlText text = doc.CreateTextNode(flag);
                    elem.AppendChild(text);
                    ccFlagsElem.AppendChild(text);
                }

                XmlElement incDirsElem = doc.CreateElement("IncDirs");
                docElem.AppendChild(incDirsElem);
                foreach (string incDir in incDirs)
                {
                    elem = doc.CreateElement("IncDir");
                    XmlText text = doc.CreateTextNode(incDir);
                    elem.AppendChild(text);
                    incDirsElem.AppendChild(elem);
                }

                XmlElement srcFilesElem = doc.CreateElement("SrcFiles");
                docElem.AppendChild(srcFilesElem);
                foreach (string srcFile in srcFiles)
                {
                    elem = doc.CreateElement("SrcFile");
                    XmlText text = doc.CreateTextNode(srcFile);
                    elem.AppendChild(text);
                    srcFilesElem.AppendChild(elem);
                }
                doc.Save(stream);
                stream.Close();
            }

        }

        public enum VARIABLE_KEY
        {
            CYGWIN_HOME,
            BRICKOS_HOME,
            XC_TOOLS_HOME,
            INC_DIRS,
            SRC_FILES,
            TARGET,
            FLAG_CC
        };


        private string _configFileName;
        private string configFile;
 
    }
}
